<template>
<div class="query-container">
<!--  搜索框-->
  <el-card class="filter-card">
    <el-form :inline="true" :model="formInline">
      <el-form-item label="用户名">
        <el-input v-model="formInline.username" style="width: 180px" placeholder="请输入用户名" clearable />
      </el-form-item>
      <el-form-item label="电话">
        <el-input v-model="formInline.phone" style="width: 180px" placeholder="请输入电话" clearable />
      </el-form-item>
      <el-form-item label="真实姓名">
        <el-input v-model="formInline.realname" style="width: 180px" placeholder="请输入真实姓名" clearable />
      </el-form-item>

      <el-form-item>
        <el-button type="primary" @click="onSubmit">搜索</el-button>
        <el-button @click="restForm()">重置</el-button>
      </el-form-item>
    </el-form>
  </el-card>
  <el-card>
    <div class="table-header">
      <el-button type="primary" @click="handleAdd">添加</el-button>
      <el-button type="danger" @click="handleBatchDelete">批量删除</el-button>
    </div>
    <el-table
      ref="multipleTableRef"
      :data="tableData"
      row-key="id"
      style="width: 100%"
      @selection-change="handleSelectionChange"
    >
      <el-table-column type="selection" width="55" />
      <el-table-column label="序号" type="index" width="80" />
      <el-table-column property="username" label="用户名" width="120" />
      <el-table-column property="phone" label="电话" width="120" />
      <el-table-column property="realname" label="真实姓名" width="120" />
      <el-table-column label="性别" width="120">
        <template #default="scope">{{ scope.row.sex=='f'?'女':scope.row.sex=='m'?'男':'' }}</template>
      </el-table-column>
      <el-table-column label="状态" width="120">
        <template #default="scope">
          <el-switch v-model="scope.row.flag" inline-prompt
                     active-text="开启" inactive-text="关闭"
                     :active-value="'0'" :inactive-value="'1'"
          />
        </template>
      </el-table-column>
      <el-table-column property="roleName" label="角色" />
      <el-table-column label="操作">
        <template #default="scope">
          <el-button size="small" @click="handleEdit(scope.$index, scope.row)">
            编辑
          </el-button>
          <el-button
            size="small"
            type="danger"
            @click="handleDelete(scope.row)"
          >
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <el-pagination
      v-model:current-page="pagination.current"
      v-model:page-size="pagination.pageSize"
      :page-sizes="[2, 5, 10,20]"
      layout="total, sizes, prev, pager, next, jumper"
      :total="pagination.total"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
  </el-card>

<!--  :close-on-click-modal="false"表示点其他地方不会自动关闭，只有点固定的地方才会关闭-->
<!--  formLoading防止重复提交，是一个禁用按钮-->
<!--  :rules="userFormRules"  设置校验规则-->
  <el-dialog v-model="dialogFormVisible" :title="dialogType=='add'?'添加':'编辑'" width="600" :close-on-click-modal="false" draggable>
    <el-form :model="userForm" ref="userFormRef" :rules="userFormRules" label-width="100px" :disabled="formLoading">

      <el-form-item label="用户名" prop="username">
<!--        :disabled="dialogType==='edit' 表示当点击的为编辑时不让修改用户名-->
        <el-input v-model="userForm.username" placeholder="请输入用户名" :disabled="dialogType==='edit'"/>
<!--        v-show-->
        <div class="form-hint" v-if="dialogType==='add'">
          用户名长度是 3-10,一旦创建不能修改,默认密码123456abc
        </div>

      </el-form-item>
      <el-form-item label="真实姓名" prop="realname">
<!--        :disabled="dialogType==='edit' 表示当点击的为编辑时不让修改用户名-->
        <el-input v-model="userForm.realname" placeholder="请输入真实姓名"/>
      </el-form-item>

      <el-form-item label="电话" prop="phone">
        <!--        :disabled="dialogType==='edit' 表示当点击的为编辑时不让修改用户名-->
        <el-input v-model="userForm.phone" placeholder="请输入电话"/>
      </el-form-item>

      <el-form-item label="性别" prop="sex">
        <el-radio-group v-model="userForm.sex">
          <el-radio value="f">女</el-radio>
          <el-radio value="m">男</el-radio>
        </el-radio-group>
      </el-form-item>

      <el-form-item label="状态" prop="flag">
        <el-switch v-model="userForm.flag" inline-prompt
                   active-text="开启" inactive-text="关闭"
                   :active-value="'0'" :inactive-value="'1'"
        />
      </el-form-item>

      <el-form-item label="角色" prop="roleId">
        <el-select v-model="userForm.roleId" placeholder="请选择角色">
          <el-option v-for="role in roleOptions"
                     :key="role.id"
                     :label="role.name"
                     :value="role.id"/>
        </el-select>
      </el-form-item>

      <el-form-item label="备注" prop="remark">
        <el-input v-model="userForm.remark"  type="textarea" placeholder="请输入备注" :rows="3"/>
      </el-form-item>

    </el-form>
    <template #footer>
      <div class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取消</el-button>
        <el-button type="primary" @click="submitForm" :loading="formLoading">
          {{dialogType==='add'?'添加':'编辑'}}
        </el-button>
      </div>
    </template>
  </el-dialog>

</div>
</template>

<script setup lang="ts">
import {onMounted, reactive, ref} from 'vue'
import type {FormInstance, TableInstance} from 'element-plus'
import {User} from "@/views/user/type";
import {ElMessage, ElMessageBox, FormRules} from "element-plus";
import {fetchUsersByCondition, addUser, editUser, checkUsernameExists,deleteUser} from "@/api/user";
import axios from "axios";
import {getRoleList} from "@/api/role";

//添加和修改-------------------------------------------------------------------------
//打开添加到弹框dialog
const dialogFormVisible = ref(false)//判定弹框刚开始时隐藏
const dialogType=ref<'add'|'edit'>('add')//设置默认为add
const userFormRef=ref<FormInstance>()
//默认进入添加和修改页面表单时可以编辑的disabled，提交时表单修改为不可编辑
//防止重复提交，提交按钮上使用
const formLoading=ref(false)
//表单的字段
const userForm = reactive({
  id: '',
  username: '',
  realname: '',
  phone: '',
  sex: 'f',
  flag: '0',
  roleId: '',
  remark: '',
})
function handleAdd() {
  dialogType.value='add'
  //重置表单 能把数据重置，校验清空
  if (userFormRef.value) userFormRef.value.resetFields()
  //经常使用Object.assign进行响应式对象的重置（赋值）,还可以使用扩展运算符
  //... 经常用于数组
  Object.assign(userForm,{
      id: '',
      username: '',
      realname: '',
      phone: '',
      sex: 'f',
      flag: '0',
      roleId: '',
      remark: '',
    })
  dialogFormVisible.value=true
}

function handleEdit(index,row) {
  dialogType.value='edit'
  if (userFormRef.value) userFormRef.value.resetFields()
  Object.assign(userForm,{
    id: row.id,
    username: row.username,
    realname: row.realname,
    phone: row.phone,
    sex: row.sex,
    flag: row.flag,
    roleId: row.roleId,
    remark: row.remark,
  })

  dialogFormVisible.value=true
}

//提交表单
function submitForm() {
  //首先校验
  userFormRef.value.validate((valid)=>{
    if (!valid) return;

    //校验通过
    formLoading.value=true
    const params={...userForm}
    //调用方法的名称
    const request=dialogType.value==='add'?addUser:editUser
    request(params).then(res=>{
      ElMessage.success(res.msg)
      dialogFormVisible.value=false
      getUsersByCondition()
    }).catch(error=>{
      ElMessage.error(`${dialogType.value==='add'?'添加':'修改'}`+'失败')
    }).finally(()=>{
      formLoading.value=false
    })
  })
}


//删除-------------------------------------------------------------------------------
//单个删除
function handleDelete(row) {
  confirmDelete([row.id])
}

//批量删除
function handleBatchDelete() {
  if (multipleSelection.value.length > 0) {
    const ids=multipleSelection.value.map(item=>item.id)

    //批量删除
    confirmDelete(ids)
  }else {
    ElMessage.error("请选择要删除的数据")
  }
}



function confirmDelete(ids: any[]) {
  ElMessageBox.confirm(
    '请您确认是否删除选中的纪录?',
    '消息',
    {
      confirmButtonText: '确认',
      cancelButtonText: '取消',
      type: 'warning',
    }
  )
    .then(async () => {
      let res = await deleteUser(ids)
      ElMessage({type: 'success', message: '删除完成',})
      pagination.current=1;
      getUsersByCondition();

    })
    .catch(() => {ElMessage({type: 'info', message: '删除取消',})
    })
}
const roleOptions = ref<{ id: number; name: string }[]>([]);

//这是一个生命周期钩子函数，作用是查询数据，并把查询到的数据赋值给下面 formInline 中定义的空变量
onMounted(()=>{
  getUsersByCondition()
  getRoleList({page:1,pageSize:999}).then(res=>{
    roleOptions.value = res.data.list.map(r=>({
      id: r.roleId,
      name:r.roleName
    }))
  })
})

//快速搜索表单
const formInline = reactive({
  username: '',
  phone: '',
  realname: '',
})

//搜索框提交
const onSubmit = () => {
  pagination.current=1
  getUsersByCondition()
}

//搜索框重置
function restForm() {
  formInline.username=""
  formInline.phone=""
  formInline.realname=""
  pagination.current=1
  getUsersByCondition()

}

//表格相关的在这下面


//multipleTableRef：表格的引入
const multipleTableRef = ref<TableInstance>()
//multipleSelection：复选框选中时变量存储在当前变量里
const multipleSelection = ref<User[]>([])

//复选框每次选中都要执行该方法
const handleSelectionChange = (val: User[]) => {
  //选中后的值赋给前面的value变量
  multipleSelection.value = val
  console.log(multipleSelection.value)
}

const tableData: User[] = reactive([])

function getUsersByCondition() {
  const params = {
    ...formInline,
    page:pagination.current,
    pageSize:pagination.pageSize
  }

  //调用axios进行访问后台数据
  fetchUsersByCondition(params).then(res=>{
    //把tableData中的数据清空,防止多次查询数据累加在一起
    tableData.length=0
    //三个点是展开运算符
    tableData.push(...res.data.list)
    pagination.total=res.data.total
  }).catch(e=>{
    ElMessage.error(e.message||"查询失败")
  })
}


//分页的参数变量

const pagination = reactive({
  current:1,
  pageSize:2,
  total:0
})

const handleSizeChange = (val: number) => {
  // console.log(`${val} items per page`)
  pagination.pageSize=val;//把后端一页多少条动态传到前端
  pagination.current=1
  getUsersByCondition()
}

const handleCurrentChange = (val: number) => {
  // console.log(`current page: ${val}`)
  pagination.current=val;//把后端传入的第几页动态传到前端
  getUsersByCondition()
}

const validateUsername = (rule: any, value: any, callback: any) => {
  if (dialogType === 'add') {
    if (value === '') {
      callback(new Error('用户名不能为空'))
    }
    if (value.length < 3 || value.length > 10) {
      callback(new Error('用户名长度必须为3-10个字符'));
      return;
    } else {
      checkUsernameExists(value).then(response => {
        const {exists} = response.data; //这部分就是异步请求 假设后端返回 { exists: boolean }
        if (exists) {
          // 用户名已存在，验证失败
          callback(new Error('该用户名已被注册，请更换'));
        } else {
          // 用户名可用，验证通过
          callback();
        }
      })
        .catch(error => {
          // 请求失败（如网络错误），提示用户
          callback(new Error('用户名校验失败，请稍后重试'));
          console.error('校验请求失败：', error);
        });
    }
  } else {
    callback();
  }

}


const userFormRules=reactive<FormRules>({
  username: [
    { validator:validateUsername, trigger: 'blur' },
    // { required: true, message: '用户名不能为空~', trigger: 'blur' },
    // { min: 3, max: 10, message: '用户名长度是 3 to 10', trigger: 'blur' },
  ],
  realname: [
    { required: true, message: '请输入真实姓名', trigger: 'blur' },
    { min: 2, max: 20, message: '昵称长度在 2 到 20 个字符之间', trigger: 'blur' }
  ],
  phone: [
    { required: true, message: '请输入手机号码', trigger: 'blur' },
    { pattern: /^1[3-9]\d{9}$/, message: '请输入正确的手机号码', trigger: 'blur' }
  ]

})

</script>

<style scoped>
.query-container {
  width: 100%;
  height: 100%;
}
.filter-card {
  border-radius: 10px;
  margin-bottom: 5px;
}
/*.result-card {
  margin-top: 5px;
}*/
.table-header {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  margin-bottom: 15px;
}
.table-foot {
  display: flex;
  justify-content: flex-start;
  align-items: center;
  margin-top: 10px;
  margin-left: 40px;
}
</style>
